from PySide6.QtWidgets import QMenu
from PySide6.QtGui import QKeySequence,QGuiApplication,QDesktopServices,QTextDocument
from custom_plain_text_edit import PlainTextEdit
from find_text_dialog import FindTextDialog

class FileMenu(QMenu):
    """文件菜单

    :param QMenu: PySide6 菜单类
    """
    def __init__(self):
        """初始化
        """
        super().__init__()
        self.setup_ui()
    
    def setup_ui(self):
        """设置菜单项
        """
        self.setTitle("文件(&F)")
        new_file = self.addAction("新建(&N)",QKeySequence.StandardKey.New)
        new_window = self.addAction("新窗口(&W)","Ctrl+Shift+N")
        open_file = self.addAction("打开(&O)",QKeySequence.StandardKey.Open)
        save_file = self.addAction("保存(&S)",QKeySequence.StandardKey.Save)
        self.addSeparator()
        save_file_as = self.addAction("另存为(&A)",QKeySequence.StandardKey.SaveAs)
        print_file = self.addAction("打印(&P",QKeySequence.StandardKey.Print)
        self.addSeparator()
        exit_ = self.addAction("退出(&X)",QKeySequence.StandardKey.Close)

class EditMenu(QMenu):
    """编辑菜单

    :param QMenu: PySide6 菜单类
    """
    def __init__(self):
        """初始化
        """
        super().__init__()
        self.setup_ui()
        self.find_text_dialog =FindTextDialog(self)
    
    def setup_ui(self):
        """设置菜单项
        """
        self.setTitle("编辑(&E)",)
        self.undo = self.addAction("撤销(&U)",QKeySequence.StandardKey.Undo)
        self.addSeparator()
        self.cut =  self.addAction("剪切(&T)",QKeySequence.StandardKey.Cut)
        self.copy = self.addAction("复制(&C)",QKeySequence.StandardKey.Copy)
        self.paste = self.addAction("粘贴(&P)",QKeySequence.StandardKey.Paste)
        self.delete = self.addAction("删除(&L)",QKeySequence.StandardKey.Delete)
        self.addSeparator()
        self.search =  self.addAction("使用Bing搜索")
        self.find_ = self.addAction("查找(&F)",QKeySequence.StandardKey.Find)
        self.find_next = self.addAction("查找下一个(&N)",QKeySequence.StandardKey.FindNext)
        self.find_previous =  self.addAction("查找上一个(&V)",QKeySequence.StandardKey.FindPrevious)
        replace =  self.addAction("替换(&R)",QKeySequence.StandardKey.Replace)
        goto =self.addAction("转到(&G)","F3")
        self.addSeparator()
        self.select_all = self.addAction("全选(&A)",QKeySequence.StandardKey.SelectAll)
        self.date_ = self.addAction("时间/日期(&D)","F5")

        # 默认状态  撤销、剪切、复制、粘贴、删除 、搜索、查找、查找上一个、查找下一个 不可用
        self.undo.setEnabled(False)
        self.cut.setEnabled(False)
        self.copy.setEnabled(False)
        self.paste.setEnabled(False)
        self.delete.setEnabled(False)
        self.search.setEnabled(False)
        self.find_.setEnabled(False)
        self.find_next.setEnabled(False)
        self.find_previous.setEnabled(False)

        # 初始化剪贴板
        self.clipbaord_ = QGuiApplication.clipboard()

    def set_event_bind(self,plain_text_edit: PlainTextEdit):
        """设置必应搜索

        :param plain_text_edit: PySide6 PlainTextEdit
        """
        # 设置状态 撤销、剪切、复制、粘贴、删除、搜索、查找、查找下一个、查找上一个
        plain_text_edit.undoAvailable.connect(self.undo.setEnabled)
        plain_text_edit.copyAvailable.connect(self.cut.setEnabled)
        plain_text_edit.copyAvailable.connect(self.copy.setEnabled)
        self.clipbaord_.dataChanged.connect(self.reset_paste_state)
        plain_text_edit.copyAvailable.connect(self.delete.setEnabled)
        plain_text_edit.copyAvailable.connect(self.search.setEnabled)
        plain_text_edit.hasText.connect(self.find_.setEnabled)
        plain_text_edit.hasText.connect(self.find_next.setEnabled)
        plain_text_edit.hasText.connect(self.find_previous.setEnabled)

        # 撤销、剪切、复制、粘贴、删除 、全选  搜索  时间 行为的绑定
        self.undo.triggered.connect(plain_text_edit.undo)
        self.cut.triggered.connect(plain_text_edit.cut)
        self.copy.triggered.connect(plain_text_edit.copy)
        self.paste.triggered.connect(plain_text_edit.paste)
        self.delete.triggered.connect(plain_text_edit.clear)
        self.select_all.triggered.connect(plain_text_edit.selectAll)
        self.search.triggered.connect(lambda: self.bing_search(plain_text_edit))
        self.date_ .triggered.connect(plain_text_edit.insert_date_time)

        # 查找 查找下一个 查找上一个
        self.find_.triggered.connect(lambda: self.show_find_dialog(plain_text_edit))
        self.find_next.triggered.connect(lambda: self.find_next_text(plain_text_edit))
        self.find_previous.triggered.connect(lambda: self.find_previous_text(plain_text_edit))

    def reset_paste_state(self):
        """重新设置粘贴状态
        """
        clipbaord_text = self.clipbaord_.text()
        if clipbaord_text:
            self.paste.setEnabled(True)
        else:
            self.paste.setEnabled(False)

    def bing_search(self,plain_text_edit: PlainTextEdit):
        """Bing搜索

        :param plain_text_edit: PySide6 PlainTextEdit
        """
        search_text = plain_text_edit.get_selected_text()
        QDesktopServices.openUrl(f"https://cn.bing.com/search?q={search_text}")      
            
    def show_find_dialog(self,plain_text_edit: PlainTextEdit):
        """显示查找对话框
        """
        # 事件绑定传入 文本编辑 | 不需要初始化传入
        self.find_text_dialog.set_event_bind(plain_text_edit)

        find_text  = plain_text_edit.get_selected_text()
        self.find_text_dialog.find_le.setText(find_text)
        
        self.find_text_dialog.show()

    def find_next_text(self,plain_text_edit: PlainTextEdit):
        """查找下一个文本

        :param plain_text_edit: PySide6 PlainTextEdit
        """
        find_text,*data, case_check_status,range_check_status = self.find_text_dialog.get_all_status()
        if case_check_status:
            flag = QTextDocument.FindFlag.FindCaseSensitively
            plain_text_edit.find(find_text,flag)
            if range_check_status:
                pass
        else:
            plain_text_edit.find(find_text)

    def find_previous_text(self,plain_text_edit: PlainTextEdit):
        """查找上一个

        :param plain_text_edit: PySide6 PlainTextEdit
        """
        find_text,*data, case_check_status,range_check_status = self.find_text_dialog.get_all_status()

        flag = QTextDocument.FindFlag.FindBackward
        if case_check_status:
            flags = flag | QTextDocument.FindFlag.FindCaseSensitively
            plain_text_edit.find(find_text,flags)
            if range_check_status:
                pass
        else:
            plain_text_edit.find(find_text,flag)
